home *** CD-ROM | disk | FTP | other *** search
- ;/* Find.c - Amiga Mail ExAll() example.
- lc -cfis -v -d0 -b0 -j73 Find.c
- blink from Find.o to Find lib lib:amiga.lib; if you don't have pragmas
- quit
- *
- * Pure code if pragmas are used.
- * Tuesday, 16-Jul-91 16:21:14, Ewout
- *
- * Compiled with SAS/C 5.10a:
- */
- /* (c) Copyright 1991 Commodore-Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice,
- and is provided "as is" without warranty of any kind, either expressed
- or implied. The entire risk as to the use of this information is
- assumed by the user.
- */
-
- #include <exec/memory.h>
- #include <dos/dosextens.h>
- #include <dos/rdargs.h>
- #include <dos/exall.h>
-
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/utility_protos.h>
-
- /* undef PRAGMAS if you don't have them */
- /* #define PRAGMAS */
- #undef PRAGMAS
- #ifdef PRAGMAS
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/utility_pragmas.h>
- #else
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
- struct Library *UtilityBase;
-
- #endif
-
- /* ExAll buffersize to receive data in */
- #define BUFFERSIZE 512
- /* Default buffersize for hold fully qualified filenames */
- #define NAMEBUFFERSIZE 512
-
- /* Used to pass data around to functions */
- struct FindControl
- {
- struct DosLibrary *fc_DOSBase;
- UBYTE *fc_Parsebuffer; /* Buffer which contains the parsed pattern */
- ULONG fc_Parselength; /* The length of this buffer */
- UBYTE *fc_Namebuffer; /* Buffer to hold the filename */
- ULONG fc_Namelength; /* The length of that buffer */
- BOOL fc_Files; /* BOOLEAN which tells if we should only look for files */
- BOOL fc_Dirs; /* BOOLEAN which tells if we should only look for dirs */
- BOOL fc_All; /* ALL keyword? */
- };
-
- static UBYTE *VersTag = "\0$VER: Find 37.1 (16.07.91)";
-
- LONG main(VOID);
- LONG ScanDirectory(struct FindControl *, UBYTE *);
- BOOL IsAssign(struct FindControl *, UBYTE *);
- LONG MultiScanDirectory(struct FindControl *, UBYTE *);
- UWORD StrLen(UBYTE *);
-
- LONG
- main(VOID)
- {
- #ifdef PRAGMAS
- struct DosLibrary *DOSBase;
- struct Library *UtilityBase;
-
- #endif
- struct RDArgs *readargs;
- LONG rargs[6];
- struct FindControl *fc;
- UBYTE *pattern, **directories;
- struct Process *process;
- APTR windowptr;
- COUNT i;
- LONG rc = 0, error = 0, fatalerror = 0;
-
- #ifndef PRAGMAS
- /* set up SysBase */
- SysBase = (*((struct Library **) 4));
- #endif
-
- /* Fail silently if < 37 */
- if (DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37))
- {
- UtilityBase = DOSBase->dl_UtilityBase;
-
- rargs[0] = 0L;
- rargs[1] = 0L;
- rargs[2] = 0L;
- rargs[3] = 0L;
- rargs[4] = 0L;
- rargs[5] = 0L;
-
- if (readargs =
- ReadArgs("PATTERN/A,DIRECTORY/A/M,FILES/S,DIRS/S,ALL/S,BUFFER/K/N",
- rargs,
- NULL))
- {
-
- if (fc = AllocMem(sizeof(struct FindControl), MEMF_CLEAR))
- {
-
- #ifdef PRAGMAS
- fc->fc_DOSBase = DOSBase;
- #endif
-
- pattern = (UBYTE *) rargs[0];
-
- fc->fc_Parselength = StrLen(pattern) * 3;
- if (fc->fc_Parsebuffer = AllocMem(fc->fc_Parselength, MEMF_CLEAR))
- {
-
- /* Make pattern uppercase for possible character classes */
- i = 0;
- while (pattern[i])
- pattern[i] = ToUpper(pattern[i++]);
-
- if ((ParsePatternNoCase(pattern,
- fc->fc_Parsebuffer,
- fc->fc_Parselength)) != -1)
- {
-
- directories = (UBYTE **) rargs[1];
-
- fc->fc_Files = (BOOL) rargs[2];
- fc->fc_Dirs = (BOOL) rargs[3];
- fc->fc_All = (BOOL) rargs[4];
-
- /*
- * Both set or cleared, clear both anyway. Easier checking later on.
- */
- if (fc->fc_Files == fc->fc_Dirs)
- fc->fc_Files = fc->fc_Dirs = FALSE;
-
- if (rargs[5])
- fc->fc_Namelength = *((LONG *) rargs[5]);
-
- if (fc->fc_Namelength < NAMEBUFFERSIZE || fc->fc_Namelength > 4096)
- fc->fc_Namelength = NAMEBUFFERSIZE;
-
- if (fc->fc_Namebuffer = AllocMem(fc->fc_Namelength, MEMF_CLEAR))
- {
- process = (struct Process *) FindTask(NULL);
- windowptr = process->pr_WindowPtr;
- process->pr_WindowPtr = (APTR) - 1L;
-
- while (*directories)
- {
-
- /*
- * Check if this is a standalone assign which appears in the assign
- * list?
- */
- if (IsAssign(fc, *directories))
- error = MultiScanDirectory(fc, *directories++);
- else
- error = ScanDirectory(fc, *directories++);
-
- if (error != 0)
- break;
- }
-
- process->pr_WindowPtr = windowptr;
-
- FreeMem(fc->fc_Namebuffer, fc->fc_Namelength);
- }
- else
- fatalerror = ERROR_NO_FREE_STORE;
- }
- else
- fatalerror = ERROR_BAD_TEMPLATE;
-
- FreeMem(fc->fc_Parsebuffer, fc->fc_Parselength);
- }
- else
- fatalerror = ERROR_NO_FREE_STORE;
- FreeMem(fc, sizeof(struct FindControl));
- }
- else
- fatalerror = ERROR_NO_FREE_STORE;
-
- FreeArgs(readargs);
-
- }
- else
- fatalerror = IoErr();
-
- /*
- * Error handling: To be informative, errors are shown while scanning, so the
- * file name which caused the error can be displayed. Other errors are shown
- * here. Errors which occured in the main loop are considered fatal, others
- * (except BREAK) just error.
- */
-
- if (fatalerror)
- {
- error = fatalerror;
- PrintFault(fatalerror, NULL);
- }
-
- SetIoErr(error);
- if (error != 0)
- {
- if (fatalerror)
- rc = RETURN_FAIL;
- else if (error == ERROR_BREAK)
- rc = RETURN_WARN;
- else
- rc = RETURN_ERROR;
- }
-
- CloseLibrary((struct Library *) DOSBase);
- }
- else
- rc = RETURN_FAIL;
- return (rc);
- }
-
-
- LONG
- ScanDirectory(struct FindControl * fc, UBYTE * source)
- {
- #ifdef PRAGMAS
- struct DosLibrary *DOSBase = fc->fc_DOSBase;
-
- #endif
- LONG vargs[1];
- struct ExAllControl *excontrol;
- struct ExAllData *ead, *buffer;
- BPTR sourcelock, namelock, olddirlock;
- BOOL exmore;
- LONG error;
-
- /*
- * Because this function may be recursively, get a fresh buffer per function call.
- */
- if (buffer = AllocMem(BUFFERSIZE, MEMF_CLEAR))
- {
-
- /* Get a lock on the start directory and make it the current directory */
- if (sourcelock = Lock(source, SHARED_LOCK))
- {
- olddirlock = CurrentDir(sourcelock);
-
- if (excontrol = AllocDosObject(DOS_EXALLCONTROL, NULL))
- {
-
- do
- {
- /* Get both file name and type to support FILES/DIRS kewords */
- exmore = ExAll(sourcelock, buffer, BUFFERSIZE, ED_TYPE, excontrol);
- error = IoErr();
- if ((exmore == NULL && (error != ERROR_NO_MORE_ENTRIES)))
- {
- PrintFault(error, source);
- break;
- }
- if (excontrol->eac_Entries == 0)
- continue;
-
- ead = buffer;
- do
- {
-
- /* Check for CTRL-C */
- if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
- {
- error = ERROR_BREAK;
- PrintFault(error, NULL);
- exmore = FALSE;
- break;
- }
-
- /*
- * Check if this one matches. If it does see if it is of the right type.
- */
- if (MatchPatternNoCase(fc->fc_Parsebuffer, ead->ed_Name))
- {
- if ((ead->ed_Type < 0 && fc->fc_Dirs == FALSE)
- || (ead->ed_Type > 0 && fc->fc_Files == FALSE))
- {
- /* It is. Lock it and get the fully qualified file name */
- if (namelock = Lock(ead->ed_Name, SHARED_LOCK))
- {
- if ((NameFromLock(namelock,
- fc->fc_Namebuffer,
- fc->fc_Namelength)) == DOSTRUE)
- {
- vargs[0] = (LONG) fc->fc_Namebuffer;
- VFPrintf(Output(), "%s\n", vargs);
- }
- else
- {
- error = IoErr();
- PrintFault(error, ead->ed_Name);
- }
- UnLock(namelock);
- }
- else
- {
- error = IoErr();
- PrintFault(error, ead->ed_Name);
- }
- }
- }
-
- /*
- * If the ALL keyword is used and this is a directory, step in it by
- * calling this function recursively.
- */
- if (ead->ed_Type > 0 && fc->fc_All)
- {
- error = ScanDirectory(fc, ead->ed_Name);
- if (error != 0)
- {
- exmore = FALSE;
- break;
- }
- }
- ead = ead->ed_Next;
- } while (ead);
- } while (exmore);
-
- FreeDosObject(DOS_EXALLCONTROL, excontrol);
-
- }
- else
- error = ERROR_NO_FREE_STORE;
-
- CurrentDir(olddirlock);
- UnLock(sourcelock);
- }
- else
- {
- error = IoErr();
- PrintFault(error, source);
- }
- FreeMem(buffer, BUFFERSIZE);
- }
- else
- error = ERROR_NO_FREE_STORE;
-
- if (error == ERROR_NO_MORE_ENTRIES)
- error = 0;
- else if (error == ERROR_NO_FREE_STORE)
- PrintFault(error, NULL);
-
- return (error);
- }
-
- BOOL
- IsAssign(struct FindControl * fc, UBYTE * name)
- {
- #ifdef PRAGMAS
- struct DosLibrary *DOSBase = fc->fc_DOSBase;
- struct Library *UtilityBase = DOSBase->dl_UtilityBase;
-
- #endif
- struct DosList *doslist;
- UBYTE *assignname;
- UCOUNT assignlength;
- LONG position;
- BOOL result = FALSE;
-
- /* First lets check if this resembles a devicename. */
- position = SplitName(name, ':', fc->fc_Namebuffer, 0, fc->fc_Namelength);
-
- if (position != -1)
- {
- /* Hmmm. */
- if (name[position] == '\0')
- {
-
- /*
- * I guess it does. Lets see if we can find it in the assign list. Keep the
- * DoSList locked as briefly as possible. This shouldn't take long.
- */
- if (doslist = AttemptLockDosList(LDF_ASSIGNS | LDF_READ))
- {
- while (doslist = NextDosEntry(doslist, LDF_ASSIGNS))
- {
-
- /* It's a BPTR */
- assignname = (UBYTE *) BADDR(doslist->dol_Name);
- assignlength = assignname[0];
-
- if ((Strnicmp(assignname + 1, fc->fc_Namebuffer, assignlength)) == 0)
- {
- /* Yup, it is. */
- result = TRUE;
- break;
- }
- }
- UnLockDosList(LDF_ASSIGNS | LDF_READ);
- } /* Can't lock DosList, don't bother */
- }
- }
- return (result);
- }
-
- LONG
- MultiScanDirectory(struct FindControl * fc, UBYTE * source)
- {
- #ifdef PRAGMAS
- struct DosLibrary *DOSBase = fc->fc_DOSBase;
-
- #endif
- struct DevProc *cproc = NULL;
- struct MsgPort *filesystemtask;
- LONG error;
-
- filesystemtask = GetFileSysTask();
-
- do
- {
- /* Find handler */
- if (cproc = GetDeviceProc(source, cproc))
- {
- SetFileSysTask(cproc->dvp_Port);
- if ((NameFromLock(cproc->dvp_Lock,
- fc->fc_Namebuffer,
- fc->fc_Namelength)) == DOSTRUE)
- {
- error = ScanDirectory(fc, fc->fc_Namebuffer);
- }
- else
- {
- error = IoErr();
- PrintFault(error, source);
- }
-
- if (error != 0)
- break;
- }
- else
- {
- error = IoErr();
- PrintFault(error, source);
- }
-
- /* Handle multi-assign */
- } while (cproc && (cproc->dvp_Flags & DVPF_ASSIGN));
-
- SetFileSysTask(filesystemtask);
- if (cproc)
- FreeDeviceProc(cproc);
-
- return (error);
- }
-
- UWORD
- StrLen(UBYTE * string)
- {
- UBYTE *length = string + 1;
-
- while (*string++ != '\0');
- return ((UWORD) (string - length));
- }
-